package com.zaicheng.cloud.netty.protocol;
/**
 @author zaicheng
 @version 1.0
 @date 2022-04-19
 @email zzc15847256473@163.com
 */

import com.dyuproject.protostuff.LinkedBuffer;
import com.dyuproject.protostuff.ProtostuffIOUtil;
import com.dyuproject.protostuff.Schema;
import com.dyuproject.protostuff.runtime.RuntimeSchema;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ProtoStuffUtil {

        private static Map<Class<?>, Schema<?>> classSchemaMap = new ConcurrentHashMap<>();

    /**
     * 获取schema
     * @param clazz
     * @param <T>
     * @return
     */
        public  static <T> Schema<T>  getSchema(Class<T> clazz){
            @SuppressWarnings("unchecked")
            Schema<T> schema = (Schema<T>) classSchemaMap.get(clazz);
            if (schema == null){
                schema = RuntimeSchema.getSchema(clazz);
                if (schema != null){
                    classSchemaMap.put(clazz,schema);
                }
            }
            return schema;
        }

    /**
     * 序列化
     * @param obj
     * @param <T>
     * @return
     */
    public  static <T> byte[]  serializer(T obj){

        Class<T> objClass = (Class<T>) obj.getClass();

        LinkedBuffer linkedBuffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
        try {
            Schema<T> schema = getSchema(objClass);
            return ProtostuffIOUtil.toByteArray(obj,schema,linkedBuffer);
        }catch (Exception e){
            throw  new  IllegalStateException(e.getMessage(),e);
        }finally {
            linkedBuffer.clear();
        }
    }

    /**
     * 反序列化
     * @param data
     * @param tClass
     * @param <T>
     * @return
     */
    public  static  <T> T deserializer(byte[] data,Class<T> tClass){

        try {
            T newInstance = tClass.newInstance();
            Schema<T> schema = getSchema(tClass);
            ProtostuffIOUtil.mergeFrom(data,newInstance,schema);
            return newInstance;
        }catch (Exception e){
            throw  new IllegalStateException(e.getMessage(),e);
        }
    }

}
